<template>
  <div class="message-tag">
    <el-card class="tag-card">
      <template #header>
        <div class="card-header">
          <div class="header-left">
            <el-input
              v-model="searchQuery"
              placeholder="搜索标签名称"
              class="search-input"
              clearable
              @clear="handleSearch"
              @keyup.enter="handleSearch"
            >
              <template #prefix>
                <el-icon><Search /></el-icon>
              </template>
            </el-input>
          </div>
          <div class="header-right">
            <el-button type="primary" @click="handleCreate">
              <el-icon><Plus /></el-icon>新建标签
            </el-button>
          </div>
        </div>
      </template>

      <!-- 标签列表 -->
      <el-table
        :data="tagList"
        border
        v-loading="loading"
        row-key="id"
        :tree-props="{ children: 'children' }"
      >
        <el-table-column type="drag" width="50" />
        <el-table-column prop="name" label="标签名称" min-width="150">
          <template #default="scope">
            <div class="tag-name">
              <el-tag
                :type="scope.row.type"
                :color="scope.row.color"
                :effect="scope.row.effect"
              >
                {{ scope.row.name }}
              </el-tag>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="code" label="标签编码" width="120" />
        <el-table-column prop="description" label="描述" min-width="200" />
        <el-table-column prop="sort" label="排序" width="80" />
        <el-table-column prop="status" label="状态" width="100">
          <template #default="scope">
            <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
              {{ scope.row.status === 'active' ? '启用' : '禁用' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="createTime" label="创建时间" width="180" />
        <el-table-column label="操作" width="200" fixed="right">
          <template #default="scope">
            <el-button type="primary" link @click="handleEdit(scope.row)">编辑</el-button>
            <el-button
              type="primary"
              link
              @click="handleAddSub(scope.row)"
            >添加子标签</el-button>
            <el-button
              type="danger"
              link
              @click="handleDelete(scope.row)"
            >删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <div class="pagination-container">
        <el-pagination
          v-model:current-page="pageNum"
          v-model:page-size="pageSize"
          :total="total"
          :page-sizes="[10, 20, 50, 100]"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </el-card>

    <!-- 标签编辑对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogType === 'create' ? '新建标签' : '编辑标签'"
      width="500px"
    >
      <el-form
        ref="formRef"
        :model="formData"
        :rules="rules"
        label-width="100px"
      >
        <el-form-item label="上级标签" v-if="dialogType === 'sub'">
          <el-input v-model="parentTag.name" disabled />
        </el-form-item>
        <el-form-item label="标签名称" prop="name">
          <el-input v-model="formData.name" placeholder="请输入标签名称" />
        </el-form-item>
        <el-form-item label="标签编码" prop="code">
          <el-input v-model="formData.code" placeholder="请输入标签编码" />
        </el-form-item>
        <el-form-item label="标签类型" prop="type">
          <el-select v-model="formData.type" placeholder="请选择标签类型">
            <el-option label="默认" value="" />
            <el-option label="成功" value="success" />
            <el-option label="警告" value="warning" />
            <el-option label="危险" value="danger" />
            <el-option label="信息" value="info" />
          </el-select>
        </el-form-item>
        <el-form-item label="标签颜色" prop="color">
          <el-color-picker v-model="formData.color" />
        </el-form-item>
        <el-form-item label="标签样式" prop="effect">
          <el-radio-group v-model="formData.effect">
            <el-radio label="light">浅色</el-radio>
            <el-radio label="dark">深色</el-radio>
            <el-radio label="plain">朴素</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="排序" prop="sort">
          <el-input-number v-model="formData.sort" :min="0" :max="999" />
        </el-form-item>
        <el-form-item label="描述" prop="description">
          <el-input
            v-model="formData.description"
            type="textarea"
            :rows="3"
            placeholder="请输入标签描述"
          />
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-radio-group v-model="formData.status">
            <el-radio label="active">启用</el-radio>
            <el-radio label="inactive">禁用</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleSave" :loading="saving">保存</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Search, Plus } from '@element-plus/icons-vue'
import {
  getMessageTagList,
  createMessageTag,
  updateMessageTag,
  deleteMessageTag,
  sortMessageTags
} from '@/api/message'

// 数据加载状态
const loading = ref(false)
const saving = ref(false)

// 分页数据
const pageNum = ref(1)
const pageSize = ref(10)
const total = ref(0)

// 搜索
const searchQuery = ref('')

// 对话框显示状态
const dialogVisible = ref(false)
const dialogType = ref('create') // create, edit, sub
const parentTag = ref(null)

// 标签列表
const tagList = ref([])

// 表单数据
const formRef = ref(null)
const formData = reactive({
  name: '',
  code: '',
  type: '',
  color: '',
  effect: 'light',
  sort: 0,
  description: '',
  status: 'active',
  parentId: null
})

// 表单验证规则
const rules = {
  name: [
    { required: true, message: '请输入标签名称', trigger: 'blur' },
    { min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
  ],
  code: [
    { required: true, message: '请输入标签编码', trigger: 'blur' },
    { pattern: /^[a-zA-Z][a-zA-Z0-9_]*$/, message: '只能包含字母、数字和下划线，且必须以字母开头', trigger: 'blur' }
  ],
  type: [{ required: true, message: '请选择标签类型', trigger: 'change' }],
  effect: [{ required: true, message: '请选择标签样式', trigger: 'change' }],
  sort: [{ required: true, message: '请输入排序号', trigger: 'blur' }],
  status: [{ required: true, message: '请选择状态', trigger: 'change' }]
}

// 初始化数据
onMounted(() => {
  fetchTagList()
})

// 获取标签列表
const fetchTagList = async () => {
  loading.value = true
  try {
    const res = await getMessageTagList({
      pageNum: pageNum.value,
      pageSize: pageSize.value,
      query: searchQuery.value
    })
    tagList.value = res.data.list
    total.value = res.data.total
  } catch (error) {
    console.error('获取标签列表失败:', error)
    ElMessage.error('获取标签列表失败')
  } finally {
    loading.value = false
  }
}

// 搜索处理
const handleSearch = () => {
  pageNum.value = 1
  fetchTagList()
}

// 分页处理
const handleSizeChange = (val) => {
  pageSize.value = val
  fetchTagList()
}

const handleCurrentChange = (val) => {
  pageNum.value = val
  fetchTagList()
}

// 新建标签
const handleCreate = () => {
  dialogType.value = 'create'
  Object.assign(formData, {
    name: '',
    code: '',
    type: '',
    color: '',
    effect: 'light',
    sort: 0,
    description: '',
    status: 'active',
    parentId: null
  })
  parentTag.value = null
  dialogVisible.value = true
}

// 编辑标签
const handleEdit = (row) => {
  dialogType.value = 'edit'
  Object.assign(formData, { ...row })
  parentTag.value = null
  dialogVisible.value = true
}

// 添加子标签
const handleAddSub = (row) => {
  dialogType.value = 'sub'
  Object.assign(formData, {
    name: '',
    code: '',
    type: '',
    color: '',
    effect: 'light',
    sort: 0,
    description: '',
    status: 'active',
    parentId: row.id
  })
  parentTag.value = row
  dialogVisible.value = true
}

// 删除标签
const handleDelete = (row) => {
  ElMessageBox.confirm('确定要删除该标签吗？', '提示', {
    type: 'warning'
  }).then(async () => {
    try {
      await deleteMessageTag(row.id)
      ElMessage.success('删除成功')
      fetchTagList()
    } catch (error) {
      console.error('删除标签失败:', error)
      ElMessage.error('删除失败')
    }
  })
}

// 保存标签
const handleSave = async () => {
  if (!formRef.value) return
  
  try {
    await formRef.value.validate()
    saving.value = true
    
    const api = dialogType.value === 'create' || dialogType.value === 'sub'
      ? createMessageTag
      : updateMessageTag
    await api(formData)
    
    ElMessage.success('保存成功')
    dialogVisible.value = false
    fetchTagList()
  } catch (error) {
    console.error('保存标签失败:', error)
    ElMessage.error(error.message || '保存失败')
  } finally {
    saving.value = false
  }
}

// 标签排序
const handleSort = async (evt) => {
  try {
    const { newIndex, oldIndex } = evt
    const newList = [...tagList.value]
    const targetRow = newList.splice(oldIndex, 1)[0]
    newList.splice(newIndex, 0, targetRow)
    
    // 更新排序号
    const sortData = newList.map((item, index) => ({
      id: item.id,
      sort: index + 1
    }))
    
    await sortMessageTags(sortData)
    ElMessage.success('排序更新成功')
    fetchTagList()
  } catch (error) {
    console.error('更新排序失败:', error)
    ElMessage.error('更新排序失败')
  }
}
</script>

<style lang="scss" scoped>
.message-tag {
  padding: 20px;

  .tag-card {
    .card-header {
      display: flex;
      justify-content: space-between;
      align-items: center;

      .header-left {
        .search-input {
          width: 200px;
        }
      }
    }

    .tag-name {
      display: flex;
      align-items: center;
      gap: 8px;
    }

    .pagination-container {
      margin-top: 20px;
      display: flex;
      justify-content: flex-end;
    }
  }
}
</style> 